﻿using System;
using System.Collections.Generic;
using LogSystem;
using UnityEngine;

namespace Yoozoo.Gameplay.City
{
    public class CityFogComponent : MonoBehaviour
    {
        [DisplayOnly]
        public int width = 200;
        [DisplayOnly]
        public int height = 200;

        public string texPropName = "_infoTex";
        
        public MeshRenderer meshRenderer;
        private Material _material;
        
        private CityFogConfig _fogConfig;
        private Texture2D _fogMaskTex;

        private static Color lockedColor = new Color(1.0f, 0, 0);
        private static Color unlockColor = new Color(0,0,0);

        private byte[,] fogArray;
        
     

        public void InitConfig(TextAsset textAsset)
        {
            if (meshRenderer)
            {
                _material = meshRenderer.material;
                _fogMaskTex = new Texture2D(width,height,TextureFormat.R8,false,false);// _material.GetTexture(texPropName) as Texture2D;
                _fogMaskTex.filterMode = FilterMode.Point;
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        _fogMaskTex.SetPixel(i,j,lockedColor);
                    }
                }
                _fogMaskTex.Apply();
                _material.SetTexture(texPropName,_fogMaskTex);
            }
            _fogConfig = JsonUtility.FromJson<CityFogConfig>(textAsset.text);
            width = _fogConfig.width;
            height = _fogConfig.height;

            fogArray = new byte[width, height];
            
            // 设置位置
            meshRenderer.transform.position = new Vector3((width * _fogConfig.fogSize/2.0f) + _fogConfig.fogOffsetX,
                _fogConfig.fogPosY,
                (height * _fogConfig.fogSize/2.0f) + _fogConfig.fogOffsetZ);
            meshRenderer.transform.localScale = new Vector3(width * _fogConfig.fogSize / 10.0f,
                1,
                height * _fogConfig.fogSize / 10.0f);

            _fogConfig.FormatConfig();
        }

        public void BuildFog(int[] unlockFogs)
        {
            foreach (var fog in unlockFogs)
            {
                UnlockFog(fog);
            }
            
            foreach (var fog in unlockFogs)
            {
                ApplyFog(fog);
            }
            
            foreach (var fog in unlockFogs)
            {
                ApplyUnlockFog(fog);
            }
            
            _fogMaskTex.Apply();
        }

        public void UpdateFog(int fogId)
        {
            UnlockFog(fogId);
            ApplyFog(fogId);
            ApplyUnlockFog(fogId);
            
            _fogMaskTex.Apply();
        }


        private void UnlockFog(int fogId)
        {
            List<Vector2Int> grids = _fogConfig.GetFogGrids(fogId);
            if (grids == null)
            {
                Debug.LogError(LogModule.CitySimulation,"不存在此迷雾区域,ID:" + fogId.ToString());
                return;   
            }
            foreach (var grid in grids)
            {
                fogArray[grid.x, grid.y] = 1;
            }
        }

        private void ApplyUnlockFog(int fogId)
        {
            List<Vector2Int> grids = _fogConfig.GetFogGrids(fogId);
            if (grids == null)
            {
                Debug.LogError(LogModule.CitySimulation,"不存在此迷雾区域,ID:" + fogId.ToString());
                return;   
            }
            
            foreach (var grid in grids)
            {
                _fogMaskTex.SetPixel(grid.x,grid.y,unlockColor);
            }
        }

        // 周围影响的未解锁迷雾
        private void ApplyFog(int fogId)
        {
            List<Vector2Int> grids = _fogConfig.GetFogGrids(fogId);
            if (grids == null)
            {
                Debug.LogError(LogModule.CitySimulation,"不存在此迷雾区域,ID:" + fogId.ToString());
                return;   
            }
            HashSet<int> fogIndexSet = new HashSet<int>();  // 防止重复写入
            foreach (var grid in grids)
            {
                for (int i = -1; i <= 1; i++)
                {
                    for (int j = -1; j <= 1; j++)
                    {
                        int idx = (grid.x + i) * 100000 + grid.y + j;
                        if (fogIndexSet.Contains(idx))
                        {
                            continue;
                        }

                        if (IsValidGird(grid.x +i ,grid.y +j) && fogArray[grid.x +i ,grid.y +j] == 1)
                        {
                            continue;
                        }
                        
                        float lockFogValue = GetLockFogValue(grid.x + i, grid.y + j);
                        if (lockFogValue > 0.0001)
                        {
                            fogIndexSet.Add(idx);
                            _fogMaskTex.SetPixel(grid.x + i, grid.y + j,new Color(lockFogValue,0,0));
                        }
                    }
                }
            }
        }

        private bool IsValidGird(int x, int y)
        {
            return x >= 0 && x < width && y >= 0 && y < height;
        }

        private float GetLockFogValue(int x, int y)
        {
            int v = 0;


            bool isEdgeTop = false;
            bool isEdgeLeft = false;
            bool isEdgeBottom = false;
            bool isEdgeRight = false;

            if (IsValidGird(x, y + 1) && fogArray[x, y + 1] == 1)
            {
                // 上面解锁，上面有边
                v |= 16;
                isEdgeTop = true;
            }

            if (IsValidGird(x-1, y) && fogArray[x-1,y] == 1)
            {
                // 左边解锁，左侧有边
                v |= 32;
                isEdgeLeft = true;
            }

            if (IsValidGird(x, y - 1) && fogArray[x, y - 1] == 1)
            {
                // 下面解锁，下面有边
                v |= 64;
                isEdgeBottom = true;
            }

            if (IsValidGird(x+1, y) && fogArray[x+1,y] == 1)
            {
                // 右边解锁，右侧有边
                v |= 128;
                isEdgeRight = true;
            }


            if (IsValidGird(x - 1, y + 1) && (fogArray[x - 1, y + 1] == 1) && (!isEdgeLeft) && (!isEdgeTop))
            {
                // 左上角有一个朝内的角，条件：左上解锁，且左侧和上侧无边。
                v |= 1;
            }

            if (IsValidGird(x - 1, y - 1) && (fogArray[x - 1, y - 1] == 1) && (!isEdgeLeft) && (!isEdgeBottom))
            {
                // 左下角有一个朝内的角，条件：左下解锁，且左侧和下侧无边。
                v |= 2;
            }

            if (IsValidGird(x + 1, y - 1) && (fogArray[x + 1, y - 1] == 1) && (!isEdgeRight) && (!isEdgeBottom))
            {
                // 右下角有一个朝内的角，条件：右下解锁，且右侧和下侧无边。
                v |= 4;
            }

            if (IsValidGird(x + 1, y + 1) && (fogArray[x + 1, y + 1] == 1) && (!isEdgeRight) && (!isEdgeTop))
            {
                // 右上角有一个朝内的角，条件：右上解锁，且右侧和上侧无边。
                v |= 8;
            }



            if (v > 0.1)
            {
                return v * 1.0f/255;
            }

            return 0;
        }
        

        private void OnDestroy()
        {
            if (_fogMaskTex)
            {
                GameObject.DestroyImmediate(_fogMaskTex);
            }
        }

#if UNITY_EDITOR
        
        
        
#endif
        
    }
}